﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows.Resources;
using TecHappy.WindowsPhone.Toolkit;
using System.ComponentModel;

namespace TecHappy.WindowsPhone.Toolkit
{
    public partial class MetroImage : UserControl
    {
        #region 依赖属性

        public ImageSource Source
        {
            get { return (ImageSource)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(ImageSource), typeof(MetroImage), new PropertyMetadata(SourceChanged));

        public Color BackgroundColor
        {
            get { return (System.Windows.Media.Color)GetValue(BackgroundColorProperty); }
            set { SetValue(BackgroundColorProperty, value); }
        }
        public static readonly DependencyProperty BackgroundColorProperty =
            DependencyProperty.Register("BackgroundColor", typeof(Color), typeof(MetroImage), new PropertyMetadata(SourceChanged));

        public Color ForegroundColor
        {
            get { return (System.Windows.Media.Color)GetValue(ForegroundColorProperty); }
            set { SetValue(ForegroundColorProperty, value); }
        }
        public static readonly DependencyProperty ForegroundColorProperty =
            DependencyProperty.Register("ForegroundColor", typeof(Color), typeof(MetroImage), new PropertyMetadata(SourceChanged));

        #endregion

        WriteableBitmap normalWB;
        WriteableBitmap pressWB;

        string path = "";
        private static void SourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            MetroImage me = sender as MetroImage;
            BitmapImage temp = e.NewValue as BitmapImage;
            if (temp != null)
                me.path = temp.UriSource.ToString();

            if (string.IsNullOrEmpty(me.path)) return;

            if (DesignerProperties.IsInDesignTool)
            {
                me.img.Source = temp;
                return;
            }

            if (me.Source != null)
            {
                Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(me.path);

                BitmapImage bitmap = me.Source as BitmapImage;
                bitmap.CreateOptions = BitmapCreateOptions.None;
                bitmap.SetSource(stream);

                me.normalWB = new WriteableBitmap(bitmap);
                me.pressWB = me.normalWB.Clone();

                SolidColorBrush foreground = Application.Current.Resources["PhoneForegroundBrush"] as SolidColorBrush;
                SolidColorBrush background = Application.Current.Resources["PhoneBackgroundBrush"] as SolidColorBrush;

                Color fore = me.ForegroundColor;
                if (fore.A == 0 && fore.B == 0 && fore.G == 0 && fore.R == 0)
                    fore = foreground.Color;

                Color back = me.BackgroundColor;
                if (back.A == 0 && back.B == 0 && back.G == 0 && back.R == 0)
                    back = background.Color;

                DrawNormalColor(me.normalWB, me.path, fore, back);
                DrawPressColor(me.pressWB, me.path, fore, back);

                me.img.Source = me.normalWB;
            }
        }

        public MetroImage()
        {
            InitializeComponent();
        }

        private void img_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            this.img.Source = normalWB;
        }
        private void img_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            this.img.Source = pressWB;
        }

        #region Draw

        private const int SizeOfArgb = 4;

        private static void DrawNormalColor(WriteableBitmap bitmap, string imagePath, Color foregroungColor, Color backgroundColor)
        {
            DrawNormalCircleColor(bitmap, imagePath, foregroungColor); //绘制圆
            DrawImageColor(bitmap, imagePath, foregroungColor); //绘制图片
        }
        private static void DrawPressColor(WriteableBitmap bitmap, string imagePath, Color foregroungColor, Color backgroundColor)
        {
            DrawPressCircleColor(bitmap, foregroungColor);
            DrawImageColor(bitmap, imagePath, backgroundColor);
        }

        /// <summary>
        /// 绘制正常状态的圆
        /// </summary>
        private static void DrawNormalCircleColor(WriteableBitmap bitmap, string url, Color color)
        {
            StreamResourceInfo streamResourceInfo = Application.GetResourceStream(new Uri("/TecHappy.WindowsPhone.Toolkit;component/Images/appbar.basecircle.rest.png", UriKind.Relative));
            BitmapImage bi = new BitmapImage();
            bi.CreateOptions = BitmapCreateOptions.None;
            bi.SetSource(streamResourceInfo.Stream);
            WriteableBitmap circleWB = new WriteableBitmap(bi);

            var pixels = bitmap.Pixels;
            var w = bitmap.PixelWidth;
            var h = bitmap.PixelHeight;
            var len = w * SizeOfArgb;

            for (var x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    int pixel = circleWB.Pixels[w * x + y];

                    byte alpha = (byte)(pixel >> 24);
                    var a = alpha + 1;
                    var col = (alpha << 24)
                             | ((byte)((color.R * a) >> 8) << 16)
                             | ((byte)((color.G * a) >> 8) << 8)
                             | ((byte)((color.B * a) >> 8));

                    pixels[w * x + y] = col;
                }
            }
        }

        /// <summary>
        /// 绘制按下状态的圆
        /// </summary>
        private static void DrawPressCircleColor(WriteableBitmap bitmap, Color color)
        {
            StreamResourceInfo streamResourceInfo = Application.GetResourceStream(new Uri("/TecHappy.WindowsPhone.Toolkit;component/Images/appbar.basecircle.rest.png", UriKind.Relative));
            BitmapImage bi = new BitmapImage();
            bi.CreateOptions = BitmapCreateOptions.None;
            bi.SetSource(streamResourceInfo.Stream);
            WriteableBitmap circle = new WriteableBitmap(bi);

            var pixels = bitmap.Pixels;
            var w = bitmap.PixelWidth;
            var h = bitmap.PixelHeight;
            var len = w * SizeOfArgb;

            int begin = -1; ;

            for (var x = 0; x < w; x++)
            {
                begin = -1;

                for (int y = 0; y < h; y++)
                {
                    int pixel = circle.Pixels[w * x + y];
                    byte alpha = (byte)(pixel >> 24);

                    if (begin == -1 && alpha > 200)
                    {
                        begin = y;
                    }

                    if (y == 48 - begin)
                    {
                        begin = -1;
                    }

                    if (begin > 0) alpha = 255;

                    var a = alpha + 1;
                    var col = (alpha << 24)
                             | ((byte)((color.R * a) >> 8) << 16)
                             | ((byte)((color.G * a) >> 8) << 8)
                             | ((byte)((color.B * a) >> 8));
                    pixels[w * x + y] = col;
                }
            }
        }

        /// <summary>
        /// 绘制中间的图形
        /// </summary>
        private static void DrawImageColor(WriteableBitmap bitmap, string imagePath, Color color)
        {
            imagePath = imagePath.TrimStart('/').TrimStart('\\');
            Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(imagePath);
            BitmapImage bi = new BitmapImage();
            bi.CreateOptions = BitmapCreateOptions.None;
            bi.SetSource(stream);
            WriteableBitmap image = new WriteableBitmap(bi);

            var pixels = bitmap.Pixels;
            var w = bitmap.PixelWidth;
            var h = bitmap.PixelHeight;
            var len = w * SizeOfArgb;

            for (var x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    int pixel = image.Pixels[w * x + y];

                    byte alpha = (byte)(pixel >> 24);
                    var a = alpha + 1;
                    var col = (alpha << 24)
                             | ((byte)((color.R * a) >> 8) << 16)
                             | ((byte)((color.G * a) >> 8) << 8)
                             | ((byte)((color.B * a) >> 8));
                    if (pixel != 0)
                        pixels[w * x + y] = col;
                }
            }
        }

        #endregion
    }
}
